๋จ์ ํ ์คํธ๋ถํฐ ์๋ํฌ์๋ ํ ์คํธ๊น์ง, ๊ฒฌ๊ณ ํ ์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํธ ์ธํ๋ผ์ ํ์ ๊ตฌ์ฑ ์์๋ฅผ ํ์ํ์ฌ ๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ ์์ ์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณด์ฅํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํธ ์ธํ๋ผ: ๊ธ๋ก๋ฒ ๊ฐ๋ฐ์ ์ํ ์ข ํฉ ๊ฒ์ฆ ํ๋ ์์ํฌ
์ค๋๋ ๋น ๋ฅด๊ฒ ๋ณํํ๋ ์ํํธ์จ์ด ๊ฐ๋ฐ ํ๊ฒฝ์์ ์๋ฐ์คํฌ๋ฆฝํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ง๊ณผ ์์ ์ฑ์ ๋ณด์ฅํ๋ ๊ฒ์ ๋ฌด์๋ณด๋ค ์ค์ํฉ๋๋ค. ๊ฒฌ๊ณ ํ ํ ์คํธ ์ธํ๋ผ๋ ๋ ์ด์ ์ฌ์น๊ฐ ์๋ ํ์์ด๋ฉฐ, ํนํ ๋ค์ํ ์ฌ์ฉ์ ํ๊ฒฝ๊ณผ ๊ธฐ๋๋ฅผ ๊ฐ์ง ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ๋ฐฐํฌ๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ ๋์ฑ ๊ทธ๋ ์ต๋๋ค. ์ด ์ข ํฉ ๊ฐ์ด๋๋ ํ๋์ ์ธ ์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํธ ์ธํ๋ผ์ ํต์ฌ ๊ตฌ์ฑ ์์๋ฅผ ํ์ํ์ฌ, ํ๋ ฅ์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ ๊ฒ์ฆ ํ๋ ์์ํฌ๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ๋ก๋๋งต์ ์ ๊ณตํฉ๋๋ค.
์ ์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํธ ์ธํ๋ผ์ ํฌ์ํด์ผ ํ๋๊ฐ?
์ธ๋ถ ์ฌํญ์ ์ดํด๋ณด๊ธฐ ์ ์, ์ข ํฉ์ ์ธ ํ ์คํธ ์ธํ๋ผ์ ํฌ์ํ๋ ๊ฒ์ด ์ ์ค์ํ์ง์ ๋ํ ๊ทผ๋ณธ์ ์ธ ์ด์ ๋ฅผ ์ดํดํด ๋ด ์๋ค:
- ๋ฒ๊ทธ ๋ฐ ์ค๋ฅ ๊ฐ์: ์ฒ ์ ํ ํ ์คํธ๋ ๊ฐ๋ฐ ์๋ช ์ฃผ๊ธฐ ์ด๊ธฐ์ ์ ์ฌ์ ์ธ ๋ฒ๊ทธ๋ฅผ ์๋ณํ๊ณ ์ ๊ฑฐํ์ฌ, ํ๋ก๋์ ํ๊ฒฝ์์ ๋น์ฉ์ด ๋ง์ด ๋๋ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํฉ๋๋ค. ๊ธ๋ก๋ฒ ์ด์ปค๋จธ์ค ํ๋ซํผ์ ์์ํด ๋ณด์ญ์์ค. ๊ฒฐ์ ๊ณผ์ ์ ๋จ์ผ ๋ฒ๊ทธ ํ๋๊ฐ ์ฌ๋ฌ ๊ตญ๊ฐ์ ํตํ์ ๊ฑธ์ณ ์์ฒ ๊ฑด์ ๊ฑฐ๋์ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค.
- ์ฝ๋ ํ์ง ํฅ์: ํ ์คํธ๋ฅผ ์์ฑํ๋ฉด ๊ฐ๋ฐ์๊ฐ ๋ ๊นจ๋ํ๊ณ ๋ชจ๋ํ๋์์ผ๋ฉฐ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ฑํ๋๋ก ์ฅ๋ คํฉ๋๋ค. ํ ์คํธ ์ผ์ด์ค๋ฅผ ๊ณ ๋ คํ๋ ํ์ ์์ฒด๊ฐ ๋ ๋์ ์ค๊ณ๋ฅผ ๊ฐ์ ํฉ๋๋ค.
- ๋ ๋น ๋ฅธ ๊ฐ๋ฐ ์ฃผ๊ธฐ: ์๋ํ๋ ํ ์คํธ๋ ๋น ๋ฅธ ํผ๋๋ฐฑ์ ๊ฐ๋ฅํ๊ฒ ํ์ฌ ๊ฐ๋ฐ์๊ฐ ์ ์ํ๊ณ ์์ ์๊ฒ ๋ฐ๋ณต ์์ ์ ์ํํ ์ ์๋๋ก ํฉ๋๋ค. ์ง์์ ์ธ ํตํฉ ํ์ดํ๋ผ์ธ์ ์ฝ๋ ๋ณ๊ฒฝ ์ ์๋์ผ๋ก ํ ์คํธ๋ฅผ ํธ๋ฆฌ๊ฑฐํ์ฌ ์ฆ๊ฐ์ ์ธ ๊ฒ์ฆ์ ๋ณด์ฅํฉ๋๋ค.
- ๋ฐฐํฌ์ ๋ํ ์์ ๊ฐ ์ฆ๊ฐ: ๊ฒฌ๊ณ ํ ํ ์คํธ ์ค์ํธ๋ ์๋ก์ด ๊ธฐ๋ฅ์ด๋ ๋ฒ๊ทธ ์์ ์ด ํ๊ท๋ฅผ ์ ๋ฐํ๊ฑฐ๋ ๊ธฐ์กด ๊ธฐ๋ฅ์ ์์์ํค์ง ์์ ๊ฒ์ด๋ผ๋ ํ์ ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ๋ณต์กํ ์ข ์์ฑ์ ๊ฐ์ง ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์ ํนํ ์ค์ํฉ๋๋ค.
- ํ์ ๊ฐํ: ์ ์ ์๋ ํ ์คํธ ํ๋ก์ธ์ค๋ ๊ฐ๋ฐ์, ํ ์คํฐ, ์ดํด๊ด๊ณ์ ๊ฐ์ ํ์ ์ ์ด์งํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ง๊ณผ ๋์์ ๋ํ ๊ณต์ ๋ ์ดํด๋ฅผ ํ์ฑํฉ๋๋ค. ๋ช ํํ ํ ์คํธ ๋ฌธ์๋ ํ์ ๋๊ตฌ๋ ๊ฒ์ฆ ์ ๋ต์ ์ดํดํ ์ ์๊ฒ ํฉ๋๋ค.
- ์ ์ง๋ณด์ ๋น์ฉ ์ ๊ฐ: ํ๋ก๋์ ํ๊ฒฝ์์ ๋ฒ๊ทธ๋ฅผ ์ฐพ์ ์์ ํ๋ ๊ฒ์ ๊ฐ๋ฐ ์ด๊ธฐ์ ๋ฐ๊ฒฌํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋น์ฉ์ด ๋ง์ด ๋ญ๋๋ค. ๊ฐ๋ ฅํ ํ ์คํธ ์ธํ๋ผ๋ ๋น์ฉ์ด ๋ง์ด ๋๋ ํ๋ก๋์ ์ฌ๊ณ ์ ๊ฐ๋ฅ์ฑ์ ์ค์ฌ์ค๋๋ค.
- ๊ธ๋ก๋ฒ ํ์ฅ์ ์ํ ํ์ฅ์ฑ: ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฑ์ฅํ๊ณ ์ ์ธ๊ณ์ ์ผ๋ก ํ์ฅ๋จ์ ๋ฐ๋ผ ์ ์ ์๋ ํ ์คํธ ์ ๋ต์ ์ฌ๋ฌ ์ง์ญ, ์ฅ์น ๋ฐ ๋ธ๋ผ์ฐ์ ์์ ์์ ์ฑ๊ณผ ์ฑ๋ฅ์ ์ ์งํ๋๋ก ๋ณด์ฅํฉ๋๋ค. ๋คํธ์ํฌ ์ง์ฐ ์๊ฐ์ด๋ ๋ก์ผ์ผ๋ณ ๋ฐ์ดํฐ ํ์์ ์ํฅ์ ๊ณ ๋ คํ์ญ์์ค.
์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํธ ์ธํ๋ผ์ ํต์ฌ ๊ตฌ์ฑ ์์
์ข ํฉ์ ์ธ ์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํธ ์ธํ๋ผ๋ ์ผ๋ฐ์ ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ๊ฒ์ฆ์ ๋ค์ํ ์ธก๋ฉด์ ๋ค๋ฃจ๋ ์ฌ๋ฌ ํต์ฌ ๊ตฌ์ฑ ์์๋ก ์ด๋ฃจ์ด์ง๋๋ค:
1. ๋จ์ ํ ์คํธ
๋จ์ ํ ์คํธ๋ ํจ์, ํด๋์ค ๋๋ ๋ชจ๋๊ณผ ๊ฐ์ ๊ฐ๋ณ ์ฝ๋ ๋จ์๋ฅผ ๊ฒฉ๋ฆฌํ์ฌ ๊ธฐ๋ฅ์ ์ ํ์ฑ์ ๊ฒ์ฆํ๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค. ์ด๋ ๋ชจ๋ ๊ฒฌ๊ณ ํ ํ ์คํธ ์ ๋ต์ ๊ธฐ์ด์ ๋๋ค.
๋๊ตฌ ๋ฐ ํ๋ ์์ํฌ:
- Jest: ํ์ด์ค๋ถ์ด ๊ฐ๋ฐํ ์ธ๊ธฐ ์๊ณ ๊ธฐ๋ฅ์ด ํ๋ถํ ํ ์คํธ ํ๋ ์์ํฌ๋ก, ์ฌ์ฉํ๊ธฐ ์ฝ๊ณ ๋ฐ์ด๋ ์ฑ๋ฅ๊ณผ ๋ด์ฅ๋ ๋ชจํน ๊ธฐ๋ฅ์ผ๋ก ์ ๋ช ํฉ๋๋ค. Jest๋ ๋ฆฌ์กํธ ํ๋ก์ ํธ์์ ๋๋ฆฌ ์ฌ์ฉ๋๋ฉฐ ํฌ๊ด์ ์ธ ์ด์ค์ ๋ฐ ๋งค์ฒ ์ธํธ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- Mocha: ์ด์ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: Chai, Assert)์ ๋ชจํน ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: Sinon.JS)๋ฅผ ์ ํํ ์ ์๋ ์ ์ฐํ๊ณ ํ์ฅ ๊ฐ๋ฅํ ํ ์คํธ ํ๋ ์์ํฌ์ ๋๋ค. Mocha๋ ๊ณ ๋๋ก ์ฌ์ฉ์ ์ ์๊ฐ ๊ฐ๋ฅํ๋ฉฐ ๋ณต์กํ ํ ์คํธ ์๋๋ฆฌ์ค์ ์ ํฉํฉ๋๋ค.
- Jasmine: ํ ์คํธ ์์ฑ์ ์ํ ๊นจ๋ํ๊ณ ๊ฐ๋ ์ฑ ์๋ ๊ตฌ๋ฌธ์ ์ ๊ณตํ๋ ํ๋ ์ฃผ๋ ๊ฐ๋ฐ(BDD) ํ๋ ์์ํฌ์ ๋๋ค. Jasmine์ ์ข ์ข ์ต๊ทค๋ฌ ํ๋ก์ ํธ์์ ์ฌ์ฉ๋๋ฉฐ ์์ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ์ฆํ๊ธฐ ์ํ ๋ค์ํ ๋งค์ฒ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- AVA: ๋ ๋น ๋ฅธ ํ ์คํธ ์คํ์ ์ํด ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ฐ์ ํ๊ณ ๋์์ฑ์ ์ฅ๋ คํ๋ ๋ฏธ๋๋ฉํ๊ณ ๋ ๋จ์ ์ธ ํ ์คํธ ํ๋ ์์ํฌ์ ๋๋ค.
์์ (Jest):
// math.js
function add(a, b) {
return a + b;
}
module.exports = add;
// math.test.js
const add = require('./math');
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
๋จ์ ํ ์คํธ๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก:
- ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ ํ ์คํธ ์์ฑ: ๊ฐ ํ ์คํธ๋ ๋จ์ ๊ธฐ๋ฅ์ ๋จ์ผ ์ธก๋ฉด์ ์ง์คํด์ผ ํฉ๋๋ค.
- AAA ํจํด(์ค๋น, ์คํ, ๊ฒ์ฆ) ๋ฐ๋ฅด๊ธฐ: ํ ์คํธ๋ฅผ ๊ตฌ์กฐํํ์ฌ ์ค์ , ์คํ ๋ฐ ๊ฒ์ฆ ๋จ๊ณ๋ฅผ ๋ช ํํ๊ฒ ์ ์ํฉ๋๋ค.
- ๋ชจ์(mock) ๋ฐ ์คํ (stub)์ ์ฌ์ฉํ์ฌ ๋จ์ ๊ฒฉ๋ฆฌ: ์ค์ ๋ฐ์ดํฐ๋ ์๋น์ค์ ์์กดํ์ง ์๋๋ก ์ธ๋ถ ์ข ์์ฑ์ ๋ชจ์ ์ฒ๋ฆฌํฉ๋๋ค.
- ๋์ ์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง ๋ชฉํ: ๋จ์ ํ ์คํธ๋ก ๊ฐ๋ฅํ ํ ๋ง์ ์ฝ๋๋ฅผ ์ปค๋ฒํ๋๋ก ๋ ธ๋ ฅํฉ๋๋ค. Istanbul๊ณผ ๊ฐ์ ๋๊ตฌ๋ ์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ์ธก์ ํ ์ ์์ต๋๋ค.
- ๋จ์ ํ ์คํธ๋ฅผ ์์ฃผ ์คํ: ๋จ์ ํ ์คํธ๋ฅผ ๊ฐ๋ฐ ์ํฌํ๋ก์ ํตํฉํ์ฌ ๋ฒ๊ทธ๋ฅผ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌํฉ๋๋ค.
2. ํตํฉ ํ ์คํธ
ํตํฉ ํ ์คํธ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค๋ฅธ ๋จ์๋ ๊ตฌ์ฑ ์์ ๊ฐ์ ์ํธ ์์ฉ์ ๊ฒ์ฆํ๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค. ์ด๋ ๊ฐ ๋ถ๋ถ์ด ์์๋๋ก ํจ๊ป ์๋ํ๋์ง ํ์ธํฉ๋๋ค.
๋๊ตฌ ๋ฐ ํ๋ ์์ํฌ:
- Jest: ํนํ ์๋ก ์ํธ ์์ฉํ๋ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ฅผ ํ ์คํธํ๋ ๋ฐ ํตํฉ ํ ์คํธ์ฉ์ผ๋ก๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- Mocha: ์ ์ ํ ์ด์ค์ ๋ฐ ๋ชจํน ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํจ๊ป ์ฌ์ฉํ๋ฉด Mocha๋ ํตํฉ ํ ์คํธ๋ฅผ ์ํ ์ ์ฐํ ํ๊ฒฝ์ ์ ๊ณตํฉ๋๋ค.
- Supertest: HTTP API ํ ์คํธ๋ฅผ ์ํด ํน๋ณํ ์ค๊ณ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. API ์๋ํฌ์ธํธ์ ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ๊ฒ์ฆํ ์ ์์ต๋๋ค. ํ๋ก ํธ์๋์ ๋ฐฑ์๋ ๊ฐ์ ์ํธ ์์ฉ์ ํ ์คํธํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
- Enzyme: ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ์ถ๋ ฅ์ ๋ ์ฝ๊ฒ ๋จ์ธ, ์กฐ์ ๋ฐ ์ํํ ์ ์๊ฒ ํด์ฃผ๋ ๋ฆฌ์กํธ์ฉ ํ ์คํธ ์ ํธ๋ฆฌํฐ์ ๋๋ค. ๊ธฐ์ ์ ์ผ๋ก๋ ๋จ์ ํ ์คํธ์ฉ์ด์ง๋ง, ์ปดํฌ๋ํธ๊ฐ ์์ ์ปดํฌ๋ํธ์ ์ด๋ป๊ฒ ํตํฉ๋๋์ง ํ ์คํธํ๋ ๋ฐ ์์ฃผ ์ฌ์ฉ๋ฉ๋๋ค.
์์ (Supertest์ Jest):
// app.js (Example Express app)
const express = require('express');
const app = express();
app.get('/users', (req, res) => {
res.json([{ id: 1, name: 'John Doe' }]);
});
module.exports = app;
// app.test.js
const request = require('supertest');
const app = require('./app');
describe('GET /users', () => {
it('should return a list of users', async () => {
const res = await request(app).get('/users');
expect(res.statusCode).toEqual(200);
expect(res.body).toEqual([{ id: 1, name: 'John Doe' }]);
});
});
ํตํฉ ํ ์คํธ๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก:
- ์ฃผ์ ํตํฉ ์ง์ ์๋ณ: ์ปดํฌ๋ํธ ๊ฐ์ ๊ฐ์ฅ ์ค์ํ ์ํธ ์์ฉ์ ํ ์คํธํ๋ ๋ฐ ์ง์คํฉ๋๋ค.
- ์ค์ ๋๋ ์๋ฎฌ๋ ์ด์ ๋ ์ข ์์ฑ ์ฌ์ฉ: ํ ์คํธ ์๊ตฌ์ ๋ฐ๋ผ ์ค์ ์ข ์์ฑ(์: ๋ฐ์ดํฐ๋ฒ ์ด์ค, API)์ ์ฌ์ฉํ ์ง ๋๋ ๋ชจ์ ์ฒ๋ฆฌํ ์ง ๊ฒฐ์ ํฉ๋๋ค.
- ๋ค์ํ ์๋๋ฆฌ์ค๋ฅผ ์ปค๋ฒํ๋ ํ ์คํธ ์์ฑ: ๊ฒฌ๊ณ ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ๊ธ์ ์ ์ธ ๊ฒฝ์ฐ์ ๋ถ์ ์ ์ธ ๊ฒฝ์ฐ ๋ชจ๋๋ฅผ ํ ์คํธํฉ๋๋ค.
- ํตํฉ ํ ์คํธ๋ฅผ ๋น๊ต์ ๋น ๋ฅด๊ฒ ์ ์ง: ํฉ๋ฆฌ์ ์ธ ์คํ ์๊ฐ์ ์ ์งํ๊ธฐ ์ํด ๋๋ฆฐ ์ธ๋ถ ์๋น์ค์ ๋ํ ์์กด์ฑ์ ์ต์ํํฉ๋๋ค.
3. ์๋ํฌ์๋(E2E) ํ ์คํธ
์๋ํฌ์๋ ํ ์คํธ๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ถํฐ ๋ฐฑ์๋ ์๋น์ค๊น์ง ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํ ์ค์ ์ฌ์ฉ์ ์ํธ ์์ฉ์ ์๋ฎฌ๋ ์ด์ ํฉ๋๋ค. ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ ์ฒด์ ์ผ๋ก ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ๊ฒ์ฆํฉ๋๋ค.
๋๊ตฌ ๋ฐ ํ๋ ์์ํฌ:
- Cypress: ๋ฐ์ด๋ ๋๋ฒ๊น ๊ธฐ๋ฅ, ์๊ฐ ์ฌํ(time travel), ์๋ ๋๊ธฐ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ํ๋์ ์ด๊ณ ๊ฐ๋ฐ์ ์นํ์ ์ธ ์๋ํฌ์๋ ํ ์คํธ ํ๋ ์์ํฌ์ ๋๋ค. Cypress๋ ์๋์ ์์ ์ฑ์ผ๋ก ์ ๋ช ํฉ๋๋ค.
- Selenium WebDriver: ์น ๋ธ๋ผ์ฐ์ ์ํธ ์์ฉ ์๋ํ๋ฅผ ์ํด ๋๋ฆฌ ์ฌ์ฉ๋๋ ๋ค์ฌ๋ค๋ฅํ ํ๋ ์์ํฌ์ ๋๋ค. Selenium์ ์ฌ๋ฌ ๋ธ๋ผ์ฐ์ ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ฅผ ์ง์ํ์ฌ ๋ณต์กํ ํ ์คํธ ์๋๋ฆฌ์ค์ ์ ํฉํฉ๋๋ค.
- Puppeteer: ๊ตฌ๊ธ์ด ๊ฐ๋ฐํ Node ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ํค๋๋ฆฌ์ค ํฌ๋กฌ ๋๋ ํฌ๋ก๋ฏธ์์ ์ ์ดํ๊ธฐ ์ํ ๊ณ ์์ค API๋ฅผ ์ ๊ณตํฉ๋๋ค. Puppeteer๋ ์น ์คํฌ๋ํ, ์๋ํ ๋ฐ ์๋ํฌ์๋ ํ ์คํธ์ ์์ฃผ ์ฌ์ฉ๋ฉ๋๋ค.
- Playwright: Puppeteer์ ์ ์ฌํ ๋ ๋ค๋ฅธ ํฌ๋ก์ค ๋ธ๋ผ์ฐ์ ์๋ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ํฌ๋กฌ, ํ์ด์ดํญ์ค, ์ฌํ๋ฆฌ, ์ฃ์ง๋ฅผ ์ง์ํฉ๋๋ค. Playwright๋ ์์ ์ฑ๊ณผ ์๋๋ฅผ ๊ฐ์กฐํฉ๋๋ค.
์์ (Cypress):
// cypress/integration/example.spec.js
describe('My First Test', () => {
it('Visits the Kitchen Sink', () => {
cy.visit('https://example.cypress.io');
cy.contains('type').click();
// Should be on a new URL which
// includes '/commands/actions'
cy.url().should('include', '/commands/actions');
// Get an input field and type into it
cy.get('.action-email').type('fake@email.com');
// Verify that the value has been updated
cy.get('.action-email').should('have.value', 'fake@email.com');
});
});
์๋ํฌ์๋ ํ ์คํธ๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก:
- ์ค์ํ ์ฌ์ฉ์ ํ๋ฆ์ ์ง์ค: ์ฌ์ฉ์๊ฐ ๊ฐ์ฅ ๋ง์ด ์ ํ ๊ฐ๋ฅ์ฑ์ด ์๋ ๊ฐ์ฅ ์ค์ํ ์๋๋ฆฌ์ค๋ฅผ ํ ์คํธํ๋ ๋ฐ ์ฐ์ ์์๋ฅผ ๋ก๋๋ค.
- ํ์ค์ ์ธ ํ ์คํธ ๋ฐ์ดํฐ ์ฌ์ฉ: ์ ํํ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํด ์ค์ ๋ฐ์ดํฐ์ ์ ์ฌํ ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ์์ฑํฉ๋๋ค. ํ์งํ ๋ฐ ๊ตญ์ ํ๋ฅผ ๊ณ ๋ คํ์ญ์์ค.
- ๊ฐ๋ฅํ ํ E2E ํ ์คํธ ์๋ํ: ์๋ E2E ํ ์คํธ๋ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๊ณ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ธฐ ์ฝ์ต๋๋ค.
- ์ ์ฉ ํ๊ฒฝ์์ E2E ํ ์คํธ ์คํ: ๋ก์ปฌ ๋จธ์ ์ด๋ ํ๋ก๋์ ํ๊ฒฝ์์ E2E ํ ์คํธ๋ฅผ ์คํํ์ง ๋ง์ญ์์ค.
- E2E ํ ์คํธ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง: ํ ์คํธ ์คํ ์๊ฐ์ ์ถ์ ํ์ฌ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์๋ณํ๊ณ ํด๊ฒฐํฉ๋๋ค.
4. ์๊ฐ์ ํ๊ท ํ ์คํธ
์๊ฐ์ ํ๊ท ํ ์คํธ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค์์ ์๋ํ์ง ์์ ์๊ฐ์ ๋ณํ๋ฅผ ๊ฐ์งํฉ๋๋ค. ์ฝ๋ ๋ณ๊ฒฝ ์ ํ์ ์ ํ๋ฆฌ์ผ์ด์ ์คํฌ๋ฆฐ์ท์ ๋น๊ตํ์ฌ ๋ถ์ผ์นํ๋ ๋ถ๋ถ์ ๊ฐ์กฐ ํ์ํฉ๋๋ค.
๋๊ตฌ ๋ฐ ํ๋ ์์ํฌ:
- Percy: ๋ค์ํ ํ ์คํธ ํ๋ ์์ํฌ ๋ฐ CI/CD ์์คํ ๊ณผ ์ํํ๊ฒ ํตํฉ๋๋ ์ธ๊ธฐ ์๋ ์๊ฐ์ ํ๊ท ํ ์คํธ ํ๋ซํผ์ ๋๋ค.
- Applitools Eyes: AI ๊ธฐ๋ฐ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ์๊ฐ์ ํ๊ท๋ฅผ ๊ฐ์งํ๋ ๋ ๋ค๋ฅธ ํฌ๊ด์ ์ธ ์๊ฐ์ ํ ์คํธ ํ๋ซํผ์ ๋๋ค.
- BackstopJS: ์๋๋ฆฌ์ค๋ฅผ ์ ์ํ๊ณ ์คํฌ๋ฆฐ์ท์ ๋น๊ตํ ์ ์๋ ์คํ ์์ค ์๊ฐ์ ํ๊ท ํ ์คํธ ๋๊ตฌ์ ๋๋ค.
- Jest Image Snapshot: ์ด๋ฏธ์ง๋ฅผ ๋น๊ตํ๊ณ ์๊ฐ์ ๋ณํ๋ฅผ ๊ฐ์งํ ์ ์๋ Jest ๋งค์ฒ์ ๋๋ค. ๊ธฐ๋ณธ์ ์ธ ์๊ฐ์ ํ๊ท ์๊ตฌ์ ๊ฐ๋จํ๊ณ ํจ๊ณผ์ ์ ๋๋ค.
์์ (Jest Image Snapshot):
// component.test.js
import React from 'react';
import renderer from 'react-test-renderer';
import MyComponent from './MyComponent';
it('renders correctly', () => {
const tree = renderer.create( ).toJSON();
expect(tree).toMatchImageSnapshot();
});
์๊ฐ์ ํ๊ท ํ ์คํธ๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก:
- ๊ธฐ์ค์ ์ค์ : ์ฐธ์กฐ์ ์ผ๋ก ์ฌ์ฉํ ์ ํ๋ฆฌ์ผ์ด์ UI์ ์ด๊ธฐ ์คํฌ๋ฆฐ์ท์ ์บก์ฒํฉ๋๋ค.
- ์๊ฐ์ ํ๊ท ํ ์คํธ๋ฅผ ์ ๊ธฐ์ ์ผ๋ก ์คํ: ์๊ฐ์ ํ๊ท ํ ์คํธ๋ฅผ CI/CD ํ์ดํ๋ผ์ธ์ ํตํฉํ์ฌ ๋ณ๊ฒฝ ์ฌํญ์ ์กฐ๊ธฐ์ ๊ฐ์งํฉ๋๋ค.
- ์๊ฐ์ ์ฐจ์ด๋ฅผ ์ ์คํ๊ฒ ๊ฒํ : ๊ฐ์ง๋ ์๊ฐ์ ์ฐจ์ด๋ฅผ ์๋์ผ๋ก ๊ฒ์ฌํ์ฌ ์๋๋ ๊ฒ์ธ์ง ์๋ํ์ง ์์ ๊ฒ์ธ์ง ํ๋จํฉ๋๋ค.
- ํฌ๋ก์ค ๋ธ๋ผ์ฐ์ ํธํ์ฑ ๊ณ ๋ ค: ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ค๋ฅธ ๋ธ๋ผ์ฐ์ ์ ์ฅ์น์์ ์ผ๊ด๋๊ฒ ๋ณด์ด๋์ง ํ์ธํฉ๋๋ค.
5. ์ ๊ทผ์ฑ ํ ์คํธ
์ ๊ทผ์ฑ ํ ์คํธ๋ ์ฅ์ ๊ฐ ์๋ ์ฌ๋๋ค์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉํ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด WCAG(์น ์ฝํ ์ธ ์ ๊ทผ์ฑ ๊ฐ์ด๋๋ผ์ธ)์ ๊ฐ์ ์ ๊ทผ์ฑ ํ์ค์ ์ค์ํ๋์ง ํ์ธํฉ๋๋ค.
๋๊ตฌ ๋ฐ ํ๋ ์์ํฌ:
- axe-core: Deque Systems์์ ๊ฐ๋ฐํ ์ธ๊ธฐ ์๋ ์ ๊ทผ์ฑ ํ ์คํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. axe-core๋ ๋ค์ํ ํ ์คํธ ํ๋ ์์ํฌ์ ํตํฉ๋ ์ ์์ผ๋ฉฐ ์ ๊ทผ์ฑ ์๋ฐ์ ๋ํ ์์ธํ ๋ณด๊ณ ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
- Lighthouse: ๊ตฌ๊ธ์ด ๊ฐ๋ฐํ ์น ์ฑ๋ฅ ๋ฐ ์ ๊ทผ์ฑ ๊ฐ์ฌ ๋๊ตฌ์ ๋๋ค. Lighthouse๋ ํฌ๋กฌ ๊ฐ๋ฐ์ ๋๊ตฌ ๋๋ Node ๋ชจ๋๋ก ์คํํ ์ ์์ต๋๋ค.
- WAVE (Web Accessibility Evaluation Tool): ์น ํ์ด์ง์ ์ ๊ทผ์ฑ์ ํ๊ฐํ ์ ์๋ ๋ธ๋ผ์ฐ์ ํ์ฅ ํ๋ก๊ทธ๋จ์ ๋๋ค.
- Pa11y: ๋ช ๋ น์ค ๋๋ ์น ์๋น์ค๋ก ์คํํ ์ ์๋ ์๋ํ๋ ์ ๊ทผ์ฑ ํ ์คํธ ๋๊ตฌ์ ๋๋ค.
์์ (axe-core์ Jest):
// accessibility.test.js
const axe = require('axe-core');
const { JSDOM } = require('jsdom');
const html = `
Hello World
`;
it('should have no accessibility violations', async () => {
const dom = new JSDOM(html);
global.document = dom.window.document;
const results = await axe.run();
expect(results.violations).toHaveLength(0);
});
์ ๊ทผ์ฑ ํ ์คํธ๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก:
- ์ ๊ทผ์ฑ ํ ์คํธ๋ฅผ ์กฐ๊ธฐ์ ํตํฉ: ๊ฐ๋ฐ ์๋ช ์ฃผ๊ธฐ์์ ๊ฐ๋ฅํ ํ ๋นจ๋ฆฌ ์ ๊ทผ์ฑ ํ ์คํธ๋ฅผ ์์ํฉ๋๋ค.
- ์๋ํ๋ ํ ์คํธ ๋๊ตฌ ์ฌ์ฉ: ์ผ๋ฐ์ ์ธ ์๋ฐ ์ฌํญ์ ์ ์ํ๊ณ ํจ์จ์ ์ผ๋ก ๋ฐ๊ฒฌํ๊ธฐ ์ํด ์ ๊ทผ์ฑ ํ ์คํธ๋ฅผ ์๋ํํฉ๋๋ค.
- ์๋ ํ ์คํธ ์ํ: ๋ ๋ณต์กํ ์ ๊ทผ์ฑ ๋ฌธ์ ๋ฅผ ์๋ณํ๊ธฐ ์ํด ์๋ํ๋ ํ ์คํธ๋ฅผ ์๋ ํ ์คํธ๋ก ๋ณด์ํฉ๋๋ค.
- ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์ ์ฐธ์ฌ: ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ง์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ์ง ํ์ธํ๊ธฐ ์ํด ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๋ก๋ถํฐ ํผ๋๋ฐฑ์ ๋ฐ์ต๋๋ค.
- ์ ๊ทผ์ฑ ํ์ค ์ต์ ์ํ ์ ์ง: ์ต์ WCAG ๊ฐ์ด๋๋ผ์ธ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์์งํฉ๋๋ค.
์ง์์ ์ธ ํตํฉ ๋ฐ ์ง์์ ์ธ ์ ๊ณต (CI/CD)
ํ ์คํธ ์ธํ๋ผ๋ฅผ CI/CD ํ์ดํ๋ผ์ธ๊ณผ ํตํฉํ๋ ๊ฒ์ ํ ์คํธ ํ๋ก์ธ์ค๋ฅผ ์๋ํํ๊ณ ๋น ๋ฅธ ํผ๋๋ฐฑ์ ๋ณด์ฅํ๋ ๋ฐ ์ค์ํฉ๋๋ค. CI/CD ๋๊ตฌ๋ ์ฝ๋ ๋ณ๊ฒฝ์ด ์ปค๋ฐ๋ ๋๋ง๋ค ์๋์ผ๋ก ํ ์คํธ๋ฅผ ์คํํ์ฌ ์ฝ๋ ํ์ง์ ๋ํ ์ฆ๊ฐ์ ์ธ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํฉ๋๋ค.
์ธ๊ธฐ ์๋ CI/CD ๋๊ตฌ:
- Jenkins: ๊ด๋ฒ์ํ ํ๋ฌ๊ทธ์ธ๊ณผ ํตํฉ์ ์ง์ํ๋ ๋๋ฆฌ ์ฌ์ฉ๋๋ ์คํ ์์ค ์๋ํ ์๋ฒ์ ๋๋ค.
- GitHub Actions: ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ ์ง์ ํตํฉ๋ CI/CD ํ๋ซํผ์ผ๋ก, ์ ํ๋ฆฌ์ผ์ด์ ๋น๋, ํ ์คํธ ๋ฐ ๋ฐฐํฌ๋ฅผ ์ํ ์ํํ ์ํฌํ๋ก๋ฅผ ์ ๊ณตํฉ๋๋ค.
- GitLab CI/CD: ๊น๋ฉ์ ํตํฉ๋ CI/CD ํ๋ซํผ์ผ๋ก, ํฌ๊ด์ ์ธ ๋ฐ๋ธ์ต์ค ์๋ฃจ์ ์ ์ ๊ณตํฉ๋๋ค.
- CircleCI: ์ฌ์ฉ ์ฉ์ด์ฑ๊ณผ ๋น ๋ฅธ ๋น๋ ์๊ฐ์ผ๋ก ์ ๋ช ํ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ CI/CD ํ๋ซํผ์ ๋๋ค.
- Travis CI: ๊นํ๋ธ์ ์ํํ๊ฒ ํตํฉ๋๋ ๋ ๋ค๋ฅธ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ CI/CD ํ๋ซํผ์ ๋๋ค.
CI/CD ํตํฉ์ ์ด์ :
- ์๋ํ๋ ํ ์คํธ: ๋ชจ๋ ์ฝ๋ ์ปค๋ฐ์ ๋ํด ํ ์คํธ๊ฐ ์๋์ผ๋ก ์คํ๋ฉ๋๋ค.
- ๋ ๋น ๋ฅธ ํผ๋๋ฐฑ: ๊ฐ๋ฐ์๋ ์์ ์ ์ฝ๋ ํ์ง์ ๋ํด ์ฆ๊ฐ์ ์ธ ํผ๋๋ฐฑ์ ๋ฐ์ต๋๋ค.
- ํฅ์๋ ํ์ : CI/CD ํ์ดํ๋ผ์ธ์ ์ ํ๋ฆฌ์ผ์ด์ ํ์ง์ ๋ํ ๊ณต์ ๋ ์๊ฐ์ ์ ๊ณตํ์ฌ ํ์ ์ ์ด์งํฉ๋๋ค.
- ๋ ๋น ๋ฅธ ๋ฐฐํฌ: ์๋ํ๋ ํ ์คํธ ๋ฐ ๋ฐฐํฌ ํ๋ก์ธ์ค๋ ๋ ๋น ๋ฅด๊ณ ๋น๋ฒํ ๋ฆด๋ฆฌ์ค๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
- ์ํ ๊ฐ์: CI/CD ํ์ดํ๋ผ์ธ์ ํ๋ก๋์ ํ๊ฒฝ์ ๋ฒ๊ทธ๊ฐ ์ ์ ๋ ์ํ์ ์ค์ฌ์ค๋๋ค.
์ธ๊ณํ ๋ฐ ํ์งํ (i18n ๋ฐ L10n) ํ ์คํธ
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ, ์ธ๊ณํ(i18n) ๋ฐ ํ์งํ(L10n) ๋ฌธ์ ๋ฅผ ํ ์คํธํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค. ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ค๋ฅธ ์ธ์ด, ๋ฌธํ ๋ฐ ์ง์ญ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ ์ํ๋์ง ํ์ธํฉ๋๋ค.
i18n ๋ฐ L10n ํ ์คํธ๋ฅผ ์ํ ์ฃผ์ ๊ณ ๋ ค ์ฌํญ:
- ํ ์คํธ ํ์ฅ ๋ฐ ์ถ์: ๋ค๋ฅธ ์ธ์ด๋ ๋์ผํ ๋ด์ฉ์ ํ์ํ๋ ๋ฐ ๋ค์ํ ์์ ๊ณต๊ฐ์ด ํ์ํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ด ํ ์คํธ ํ์ฅ ๋ฐ ์ถ์๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋์ง ํ ์คํธํฉ๋๋ค.
- ๋ ์ง ๋ฐ ์๊ฐ ํ์: ๋ ์ง ๋ฐ ์๊ฐ ํ์์ ์ง์ญ๋ง๋ค ํฌ๊ฒ ๋ค๋ฆ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ด ๊ฐ ๋ก์ผ์ผ์ ๋ํด ๋ ์ง์ ์๊ฐ์ ์ฌ๋ฐ๋ฅด๊ฒ ํ์ํ๋์ง ํ์ธํฉ๋๋ค.
- ํตํ ํ์: ํตํ ๊ธฐํธ ๋ฐ ํ์ ๊ท์น์ ๊ตญ๊ฐ๋ง๋ค ๋ค๋ฆ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ด ํตํ ํ์์ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ๋์ง ํ ์คํธํฉ๋๋ค.
- ์ซ์ ํ์: ์ซ์ ๊ตฌ๋ถ ๊ธฐํธ(์: ์ผํ, ๋ง์นจํ)๋ ์ง์ญ๋ง๋ค ๋ค๋ฆ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ซ์๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ํ์ํ๋์ง ํ์ธํฉ๋๋ค.
- ๋ฌธ์ ์ธ์ฝ๋ฉ: ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ง์ํด์ผ ํ๋ ๋ชจ๋ ์ธ์ด๋ฅผ ์ง์ํ๋ ๋ฌธ์ ์ธ์ฝ๋ฉ(์: UTF-8)์ ์ฌ์ฉํฉ๋๋ค.
- ์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ์ผ๋ก ์ฐ๋(RTL) ์ธ์ด: ์ ํ๋ฆฌ์ผ์ด์ ์ด ์๋์ด ๋ฐ ํ๋ธ๋ฆฌ์ด์ ๊ฐ์ RTL ์ธ์ด๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ๋์ง ํ ์คํธํฉ๋๋ค.
- ๋ฒ์ญ ์ ํ์ฑ: ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ชจ๋ ํ ์คํธ๊ฐ ๋์ ์ธ์ด๋ก ์ ํํ๊ฒ ๋ฒ์ญ๋์๋์ง ํ์ธํฉ๋๋ค.
i18n ๋ฐ L10n ํ ์คํธ๋ฅผ ์ํ ๋๊ตฌ ๋ฐ ๊ธฐ์ :
- ์์ฌ ํ์งํ(Pseudo-localization): ํ ์คํธ๋ฅผ ํ ์คํธ ํ์ฅ ๋ฐ ํน์ ๋ฌธ์์ ๊ฐ์ ๋ฒ์ญ ํจ๊ณผ๋ฅผ ์๋ฎฌ๋ ์ด์ ํ๋ ์ธ๊ณต ๋ฌธ์์ด๋ก ๋์ฒดํฉ๋๋ค.
- ๊ตญ์ ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ: ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋์์ ํ์งํ ์์ ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด `i18next` ๋๋ `Globalize.js`์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- ์๋ํ๋ ํ์งํ ํ ์คํธ: `LokiJS`์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ํ์งํ๋ ์ฝํ ์ธ ์ ์๊ฐ์ ๋ชจ์์ ํ์ธํฉ๋๋ค.
- ์๋ ํ์งํ ํ ์คํธ: ๋ฒ์ญ์ ์ ํ์ฑ๊ณผ ๋ฌธํ์ ์ ์ ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ์์ด๋ฏผ์ ํ ์คํธ ๊ณผ์ ์ ์ฐธ์ฌ์ํต๋๋ค.
์์: ๋ ์ง ํ์ ๋ฌธ์ ํ ์คํธ
์ ํ๋ฆฌ์ผ์ด์ ์ด MM/DD/YYYY ํ์์ผ๋ก ๋ ์ง๋ฅผ ํ์ํ๋ ์๋๋ฆฌ์ค๋ฅผ ๊ณ ๋ คํด ๋ด ์๋ค. ์ ๋ฝ ์ฌ์ฉ์์ ๊ฒฝ์ฐ, ์ผ๋ฐ์ ์ผ๋ก DD/MM/YYYY๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ํผ๋์ค๋ฌ์ธ ์ ์์ต๋๋ค. ํ์งํ ํ ์คํธ๋ ๋ก์ผ์ผ์ ์ ๋ฝ ๊ตญ๊ฐ๋ก ์ค์ ํ๊ณ ๋ ์ง๊ฐ DD/MM/YYYY ํ์์ผ๋ก ์ฌ๋ฐ๋ฅด๊ฒ ํ์๋๋์ง ํ์ธํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค.
์ฑ๋ฅ ํ ์คํธ
์ฑ๋ฅ ํ ์คํธ๋ ํนํ ๋ค์ํ ๋คํธ์ํฌ ์กฐ๊ฑด์ ๊ฐ์ง ๊ธ๋ก๋ฒ ์ฌ์ฉ์ ๊ธฐ๋ฐ์ ์๋น์ค๋ฅผ ์ ๊ณตํ ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ ์ํ๊ฒ ๋ก๋๋๊ณ ํจ์จ์ ์ผ๋ก ์๋ตํ๋๋ก ๋ณด์ฅํ๋ ๋ฐ ์ค์ํฉ๋๋ค.
์ฃผ์ ์ฑ๋ฅ ํ ์คํธ ์ ํ
- ๋ถํ ํ ์คํธ: ์์ ์ฌ์ฉ์ ๋ถํ ํ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ์ ํ๊ฐํฉ๋๋ค.
- ์คํธ๋ ์ค ํ ์คํธ: ์์ ๋ถํ๋ฅผ ์ด๊ณผํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ๊ณ์ ์ ๊ฒฐ์ ํฉ๋๋ค.
- ๋ด๊ตฌ์ฑ ํ ์คํธ: ์ผ๊ด๋ ๋ถํ ํ์์ ์ฅ๊ธฐ๊ฐ ๋์์ ์์ ์ฑ์ ๊ฒ์ฆํฉ๋๋ค.
- ์คํ์ดํฌ ํ ์คํธ: ๊ฐ์์ค๋ฝ๊ณ ๊ทน๋จ์ ์ธ ๋ถํ ์ฆ๊ฐ์ ๋ํ ๋ฐ์์ ํ๊ฐํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ์ฑ๋ฅ ํ ์คํธ ๋๊ตฌ
- WebPageTest: ์ ์ธ๊ณ ์ฌ๋ฌ ์์น์์ ์น์ฌ์ดํธ ์ฑ๋ฅ์ ํ ์คํธํ๋ ์คํ ์์ค ๋๊ตฌ๋ก, ์์ธํ ๋ฉํธ๋ฆญ๊ณผ ์๊ฐํ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- Lighthouse: ํฌ๋กฌ ๊ฐ๋ฐ์ ๋๊ตฌ์ ํตํฉ๋์ด ์์ผ๋ฉฐ, Lighthouse๋ ์ฑ๋ฅ ๊ฐ์ฌ ๋ฐ ํ์ด์ง ๋ก๋ ์๊ฐ์ ๊ฐ์ ํ๊ธฐ ์ํ ์คํ ๊ฐ๋ฅํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํฉ๋๋ค.
- PageSpeed Insights: ์น ํ์ด์ง์ ์ฝํ ์ธ ๋ฅผ ๋ถ์ํ๊ณ ํด๋น ํ์ด์ง๋ฅผ ๋ ๋น ๋ฅด๊ฒ ๋ง๋ค๊ธฐ ์ํ ์ ์์ ์ ๊ณตํ๋ ๊ตฌ๊ธ์ ๋๊ตฌ์ ๋๋ค.
- k6: ๊ฐ๋ฐ์ ๋ฐ ๋ฐ๋ธ์ต์ค๋ฅผ ์ํด ์ค๊ณ๋ ์คํ ์์ค ๋ถํ ํ ์คํธ ๋๊ตฌ๋ก, ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์ฑ๋ฅ ํ ์คํธ๋ฅผ ์คํฌ๋ฆฝํ ํ ์ ์์ต๋๋ค.
- Artillery: Node.js๋ก ์์ฑ๋ ํ๋์ ์ธ ๋ถํ ํ ์คํธ ํ๋ซํผ์ผ๋ก, ๋ณต์กํ ์ฑ๋ฅ ์๋๋ฆฌ์ค์ ๋ํ ํ์ฅ์ฑ๊ณผ ํ์ฅ์ฑ์ ์ ๊ณตํฉ๋๋ค.
์ฑ๋ฅ ํ ์คํธ๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
- ์ฌ๋ฌ ์ง๋ฆฌ์ ์์น์์ ํ ์คํธ: ๋ค๋ฅธ ์ง์ญ์ ์ค์ ์ฌ์ฉ์ ์ ๊ทผ์ ์๋ฎฌ๋ ์ด์ ํ์ฌ ์ง๋ฆฌ์ ์ผ๋ก ํน์ ํ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์๋ณํฉ๋๋ค.
- ๋ค์ํ ๋คํธ์ํฌ ์กฐ๊ฑด ์๋ฎฌ๋ ์ด์ : ๋ค์ํ ์ฌ์ฉ์ ํ๊ฒฝ ์ ๋ฐ์ ์ฑ๋ฅ์ ์ดํดํ๊ธฐ ์ํด ๋ค์ํ ๋คํธ์ํฌ ์๋์ ์ง์ฐ ์๊ฐ์ ์๋ฎฌ๋ ์ด์ ํฉ๋๋ค.
- ์ด๋ฏธ์ง ๋ฐ ์์ฐ ์ต์ ํ: ๋ค์ด๋ก๋ ์๊ฐ์ ์ต์ํํ๊ธฐ ์ํด ํ์ผ ํฌ๊ธฐ๋ฅผ ์ค์ ๋๋ค.
- ๋ธ๋ผ์ฐ์ ์บ์ฑ ํ์ฉ: ์บ์ฑ ์ ๋ต์ ์ฌ์ฉํ์ฌ ์๋ฒ ๋ถํ๋ฅผ ์ค์ด๊ณ ์ฌ๋ฐฉ๋ฌธ์์ ํ์ด์ง ๋ก๋ ์๊ฐ์ ๊ฐ์ ํฉ๋๋ค.
- ์๋ฒ ์ธก ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง: ํ๋ก ํธ์๋ ์ฑ๋ฅ์ ์ํฅ์ ๋ฏธ์น ์ ์๋ ์๋ฒ์ ๋ณ๋ชฉ ํ์์ ์๋ณํฉ๋๋ค.
๋ชจ๋ํฐ๋ง ๋ฐ ๊ด์ฐฐ ๊ฐ๋ฅ์ฑ
๊ฒฌ๊ณ ํ ๋ชจ๋ํฐ๋ง ๋ฐ ๊ด์ฐฐ ๊ฐ๋ฅ์ฑ ๊ดํ์ ๊ตฌํํ๋ฉด ํ๋ก๋์ ํ๊ฒฝ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๋ฐ ์ฑ๋ฅ์ ๋ํ ์ค์๊ฐ ํต์ฐฐ๋ ฅ์ ํ๋ณดํ์ฌ ๊ธ๋ก๋ฒ ์ฌ์ฉ์์๊ฒ ์ํฅ์ ๋ฏธ์น๋ ๋ฌธ์ ๋ฅผ ์ฌ์ ์ ์๋ณํ๊ณ ํด๊ฒฐํ ์ ์์ต๋๋ค.
์ฃผ์ ๋ชจ๋ํฐ๋ง ๋ฉํธ๋ฆญ
- ์ค๋ฅ์จ: ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ์๋ณํ๊ธฐ ์ํด ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ํ๋ ์ค๋ฅ์ ๋น๋๋ฅผ ์ถ์ ํฉ๋๋ค.
- ์๋ต ์๊ฐ: ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ๋ํ๋ด๋ ์ฌ์ฉ์ ์์ฒญ์ ๋ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋ต ์๊ฐ์ ๋ชจ๋ํฐ๋งํฉ๋๋ค.
- ๋ฆฌ์์ค ํ์ฉ๋: ์๋ฒ์ CPU, ๋ฉ๋ชจ๋ฆฌ ๋ฐ ๋์คํฌ ์ฌ์ฉ๋์ ์ถ์ ํ์ฌ ๋ฆฌ์์ค ์ ์ฝ์ ์๋ณํฉ๋๋ค.
- ์ฌ์ฉ์ ๊ฒฝํ ๋ฉํธ๋ฆญ: ์ฌ์ฉ์ ๊ฒฝํ์ ์ดํดํ๊ธฐ ์ํด ํ์ด์ง ๋ก๋ ์๊ฐ, ์ฒซ ๋ฐ์ดํธ๊น์ง์ ์๊ฐ(TTFB) ๋ฐ ์ฌ์ฉ์ ์ํธ ์์ฉ๊ณผ ๊ฐ์ ํต์ฌ ์ฑ๊ณผ ์งํ(KPI)๋ฅผ ์ธก์ ํฉ๋๋ค.
๋ชจ๋ํฐ๋ง ๋ฐ ๊ด์ฐฐ ๊ฐ๋ฅ์ฑ ๋๊ตฌ
- New Relic: ์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ, ์ธํ๋ผ ๋ฐ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ํ ์ค์๊ฐ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํ๋ ํฌ๊ด์ ์ธ ๋ชจ๋ํฐ๋ง ํ๋ซํผ์ ๋๋ค.
- Datadog: ์ ์ฒด ์คํ ๊ด์ฐฐ ๊ฐ๋ฅ์ฑ์ ์ ๊ณตํ๋ ๋ชจ๋ํฐ๋ง ๋ฐ ๋ถ์ ํ๋ซํผ์ผ๋ก, ์ธํ๋ผ ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ ๋ฉํธ๋ฆญ, ๋ก๊ทธ ๋ฐ ์ถ์ ์ ์ถ์ ํ ์ ์์ต๋๋ค.
- Sentry: ์ค์๊ฐ์ผ๋ก ์ค๋ฅ๋ฅผ ์๋ณํ๊ณ ํด๊ฒฐํ๋ ๋ฐ ๋์์ด ๋๋๋ก ์ค๊ณ๋ ์ค๋ฅ ์ถ์ ๋ฐ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง ํ๋ซํผ์ ๋๋ค.
- Prometheus: ํด๋ผ์ฐ๋ ๋ค์ดํฐ๋ธ ํ๊ฒฝ์ ์ํด ์ค๊ณ๋ ์คํ ์์ค ๋ชจ๋ํฐ๋ง ๋ฐ ๊ฒฝ๊ณ ํดํท์ ๋๋ค.
- Grafana: ๋ค์ํ ๋ฐ์ดํฐ ์์ค์ ๋ฉํธ๋ฆญ์ ์๊ฐํํ๊ณ ๋์๋ณด๋๋ฅผ ์์ฑํ ์ ์๋ ์คํ ์์ค ๋ฐ์ดํฐ ์๊ฐํ ๋๊ตฌ์ ๋๋ค.
๋ชจ๋ํฐ๋ง ๋ฐ ๊ด์ฐฐ ๊ฐ๋ฅ์ฑ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
- ์ค์ ์ง์ค์ ๋ก๊น ๊ตฌํ: ์ฌ์ด ๋ถ์์ ์ํด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ชจ๋ ๊ตฌ์ฑ ์์์์ ๋ก๊ทธ๋ฅผ ์ค์ ์์น์ ์์งํฉ๋๋ค.
- ์ค์ ์ด๋ฒคํธ์ ๋ํ ๊ฒฝ๊ณ ์ค์ : ์ค๋ฅ, ์ฑ๋ฅ ์ ํ ๋๋ ๋ณด์ ์นจํด์ ๊ฐ์ ์ค์ํ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋ ์๋ฆผ์ ๋ฐ๋๋ก ๊ฒฝ๊ณ ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
- ๋ถ์ฐ ์ถ์ ์ฌ์ฉ: ์ ํ๋ฆฌ์ผ์ด์ ์ ํตํด ์์ฒญ์ด ํ๋ฅผ ๋ ์ถ์ ํ์ฌ ๋ณ๋ชฉ ํ์ ๋ฐ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์๋ณํ๋ ๋ถ์ฐ ์ถ์ ์ ๊ตฌํํฉ๋๋ค.
- ๋์๋ณด๋๋ก ๋ฐ์ดํฐ ์๊ฐํ: ์ฃผ์ ๋ฉํธ๋ฆญ์ ์๊ฐํํ๊ณ ์๊ฐ ๊ฒฝ๊ณผ์ ๋ฐ๋ฅธ ์ถ์ธ๋ฅผ ์๋ณํ๊ธฐ ์ํด ๋์๋ณด๋๋ฅผ ์์ฑํฉ๋๋ค.
- ๋ชจ๋ํฐ๋ง ์ ๋ต์ ์ง์์ ์ผ๋ก ๊ฒํ ๋ฐ ๊ฐ์ : ๋ฌธ์ ๋ฅผ ์๋ณํ๊ณ ํด๊ฒฐํ๋ ๋ฐ ํ์ํ ์ ๋ณด๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์บก์ฒํ๊ณ ์๋์ง ํ์ธํ๊ธฐ ์ํด ๋ชจ๋ํฐ๋ง ์ ๋ต์ ์ ๊ธฐ์ ์ผ๋ก ๊ฒํ ํฉ๋๋ค.
ํ ์คํธ ๋ฌธํ ๊ตฌ์ถ
๊ฒฌ๊ณ ํ ํ ์คํธ ์ธํ๋ผ๋ ๊ทธ๊ฒ์ ์ง์ํ๋ ๋ฌธํ๋งํผ๋ง ํจ๊ณผ์ ์ ๋๋ค. ํ ์คํธ ๋ฌธํ๋ฅผ ๊ตฌ์ถํ๋ ค๋ฉด ๊ฐ๋ฐ์, ํ ์คํฐ๋ถํฐ ์ ํ ๊ด๋ฆฌ์, ์ดํด๊ด๊ณ์์ ์ด๋ฅด๊ธฐ๊น์ง ๊ฐ๋ฐํ ๋ชจ๋ ๊ตฌ์ฑ์์ ํ์ ์ด ํ์ํฉ๋๋ค.
ํ ์คํธ ๋ฌธํ์ ํต์ฌ ์์:
- ๊ณต๋ ์ฑ ์: ํ ์คํธ๋ QA ํ๋ง์ ์ฑ ์์ด ์๋๋ผ ๋ชจ๋ ์ฌ๋์ด ์ฝ๋ ํ์ง์ ๋ณด์ฅํ ์ฑ ์์ด ์์ต๋๋ค.
- ์กฐ๊ธฐ ํ ์คํธ: ํ ์คํธ๋ ๋์ค์ ์๊ฐํ ๊ฒ์ด ์๋๋ผ ๊ฐ๋ฐ ์๋ช ์ฃผ๊ธฐ ์ด๊ธฐ์ ์์๋์ด์ผ ํฉ๋๋ค.
- ์๋ํ: ์๋ ์์ ์ ์ค์ด๊ณ ํจ์จ์ฑ์ ๋์ด๊ธฐ ์ํด ๊ฐ๋ฅํ ํ ๋ง์ ํ ์คํธ ํ๋ก์ธ์ค๋ฅผ ์๋ํํฉ๋๋ค.
- ์ง์์ ์ธ ๊ฐ์ : ํ ์คํธ ํ๋ก์ธ์ค๊ฐ ํจ๊ณผ์ ์ด๊ณ ํจ์จ์ ์ธ์ง ํ์ธํ๊ธฐ ์ํด ์ ๊ธฐ์ ์ผ๋ก ๊ฒํ ํ๊ณ ๊ฐ์ ํฉ๋๋ค.
- ํผ๋๋ฐฑ ๋ฃจํ: ํ ์คํธ ๊ฒฐ๊ณผ๋ฅผ ๊ณต์ ํ๊ณ ๊ฐ์ ํ ์์ญ์ ์๋ณํ๊ธฐ ์ํ ํผ๋๋ฐฑ ๋ฃจํ๋ฅผ ์ค์ ํฉ๋๋ค.
- ํ๋ จ ๋ฐ ๊ต์ก: ๋ชจ๋ ์ฌ๋์ด ํ ์คํธ ๋ ธ๋ ฅ์ ๊ธฐ์ฌํ๋ ๋ฐ ํ์ํ ๊ธฐ์ ๊ณผ ์ง์์ ๊ฐ์ถ๋๋ก ํ๋ จ๊ณผ ๊ต์ก์ ์ ๊ณตํฉ๋๋ค.
- ์ฑ๊ณต ์ถํ: ํ์ง์ ์ค์์ฑ์ ๊ฐํํ๊ธฐ ์ํด ํ ์คํธ์์์ ์ฑ๊ณต์ ์ธ์ ํ๊ณ ์ถํํฉ๋๋ค.
๊ฒฐ๋ก
์ข ํฉ์ ์ธ ์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํธ ์ธํ๋ผ๋ฅผ ๊ตฌ์ถํ๋ ๊ฒ์ ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ์๋ฐ์คํฌ๋ฆฝํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ๊ณ ๋ฐฐํฌํ๋ ๋ชจ๋ ์กฐ์ง์๊ฒ ์ค์ํ ํฌ์์ ๋๋ค. ๋จ์, ํตํฉ, ์๋ํฌ์๋, ์๊ฐ์ ํ๊ท ๋ฐ ์ ๊ทผ์ฑ ํ ์คํธ๋ฅผ ํตํฉํ๊ณ ์ด๋ฅผ CI/CD ํ์ดํ๋ผ์ธ์ ํตํฉํจ์ผ๋ก์จ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ง, ์์ ์ฑ ๋ฐ ํ์ฅ์ฑ์ ๋ณด์ฅํ ์ ์์ต๋๋ค. ๋ค์ํ ์ง์ญ๊ณผ ๋ฌธํ์ ๊ฑธ์ณ ์ํํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๊ธฐ ์ํด ์ธ๊ณํ ๋ฐ ํ์งํ, ์ฑ๋ฅ ๋ฐ ๋ชจ๋ํฐ๋ง์ ๋ฏธ๋ฌํ ์ฐจ์ด๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค. ํ ์คํธ ๋ฌธํ๋ฅผ ์์ฉํ๋ฉด ํ์ด ์์ ๊ฐ์ ๊ฐ์ง๊ณ ๊ณ ํ์ง ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์๊ฒ ๋์ด ๊ถ๊ทน์ ์ผ๋ก ๊ธ๋ก๋ฒ ์์ฅ์์ ๋ ํฐ ๊ณ ๊ฐ ๋ง์กฑ๊ณผ ๋น์ฆ๋์ค ์ฑ๊ณต์ผ๋ก ์ด์ด์ง ๊ฒ์ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ฐ์ ํ๊ณ ์ฌ์ฉ์ ์๊ตฌ์ ๋ํ ์ดํด๊ฐ ๊น์ด์ง์ ๋ฐ๋ผ ํ ์คํธ ์ ๋ต์ ์ ๊ธฐ์ ์ผ๋ก ๊ฒํ ํ๊ณ ์กฐ์ ํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค.